/**
 * <p>Title: MainEllipse</p>
 * Description: CS 235 Assignment 2 
 * 	    Contains the methods to create an Ellipse, View an Ellipse History, based on major and minor axes and .txt files
 * @author JGroup 7: Nicholas A. Peterson, Dan Prayfrock, Tyler Rasmussen, John Feia
 * @date   Nov 4th 2011
 */

package a2;




import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * A simple textual interface example exercising the Ellipse class.
 */
public class MainEllipse {

	public static PrintWriter input = null;																			//Used for Printing and Saving Data
	public static PrintWriter output = null;																	 	//Used for Printing and Saving Data
	
	public static void main (String[] argv) throws IOException {													//Start
    (new EllipseTUI()).start();
    
  }
}







/**
 * A simple text-based user interface for creating and exercising an Ellipse with Enumerated Menu Options
 */
class EllipseTUI {
	static EllipseArray ellipses;																					//Data Type EllipseArray called ellipse
 	private Scanner in;																								//input from user
 	private java.io.PrintStream out = System.out;																	//console printout

 	enum Choice{NO_CHOICE,MAJ_AXS,MIN_AXS,AREA,CIRCUMF,NEW,HIST,SAVE;}												//Enumerated menu options


  /**
   * Create a user interface.
   */
  public EllipseTUI () {	
    this.ellipses = null;																		
    this.in = new Scanner(System.in);
  }

  

  /**
   * Run the user interface.
   * @require num > 0
   * @ensure EllipseArray[i>0]
   */
  //Start
  public void start () throws IOException  {
	int num=readIntWithPrompt("How many Ellipses do you want to store.");											//user input for EllipseArray Size
	this.ellipses = new EllipseArray((num));																	    //creation of EllipseArray with user size
	assert num > 0;
	historyEllipse();																							    //fill EllipseArray with pre-existing values
	Choice choice;																									//Enumerated Data Type Choice called choice
    choice = Choice.NO_CHOICE;																						//choice initialized to NO_CHOICE
    
    while (choice != Choice.SAVE) {																					
      displayMenu();																								//Console Menu Display
      choice = executeChoice(choice);																				//sets choice to enumerated value and executes command or query
      
    switch(choice) {
      case MAJ_AXS: out.println("Major axis is    " + ellipses.get().majorAxis());       break;						//Current Major Axis value
      case MIN_AXS: out.println("Minor axis is    " + ellipses.get().minor_axis());      break;						//Current Minor Axis value
      case AREA   : out.println("Area is          " + ellipses.get().area());            break;						//Area of Current Major Axis and Minor Axis values
      case CIRCUMF: out.println("Circumference is " + ellipses.get().circumference());   break; 					//Circumference of Current Major Axis and Minor Axis values
      case NEW    : createEllipse();										             break;						//Create new Ellipse with user input for Major and Minor Axes
      case HIST   : out.println(this.ellipses);											 break;						//Displays the History of Ellipse's values
      case SAVE   : out.println(this.ellipses);transfer();System.exit(0);	             break;						//Saves current entries to .txt document
      default     : out.println("I try again");							  	             break; 					//default 
      }  
    }
  } 
 
   /**
 	 * Create a new Ellipse with the specified major and minor axes.
	 * The axes must be non-negative.
	 * @Require  major_axis > 0 && minor_axis > 0 || if ( major_axis == minor_axis && major_axis !=0 )|| ( major_axis == minor_axis && major_axis !=1 );
	 * @Ensure  circumference != NaN && area > 0;
	 */
  //Create a new Ellipse
  private void createEllipse () {
	  
	    int major = -1;																																	//Major Axes
	    int minor = -1;																																	//Minor Axes
	    while (major < 0)      major = readIntWithPrompt("Ellipse maj axis (a non-negative integer): ");MainEllipse.input.printf("%4d  ", major);		//User Input for Major Axes
	    while (minor < 0)      minor = readIntWithPrompt("Ellipse min axis (a non-negative integer): ");MainEllipse.input.printf("%4d  ", minor);		//User Input for Minor Axes
	    assert major >  0 && minor >  0;																												//precondition challenge
	    assert major != 0 && minor != 0;																												//precondition challenge	    																								   
	    this.ellipses.AddEllipse( new Ellipse(major,minor) );																							//Creation of new Ellipse and adds to current EllipseArray
	  }
  
	 /**
	   * Writes current Ellipse to .txt file.
	   * 
	   */
  //Transfer current library of Ellipses to external .txt file
	  public void transfer() throws IOException{																	
		  MainEllipse.input.close();																													//Closes out.txt				
		  int major = -1;																																//Major variable
		  int minor = -1;																																//Minor variable
          File fileIn = new File("out.txt");									 																	    //File out.txt Creation
		  MainEllipse.output = new PrintWriter(new FileWriter(fileIn));																					//Writes to out.txt
		  Scanner inF = new Scanner(new FileReader("in.txt"));																						    //Reader for in.txt File
		
		     while(inF.hasNext()){
			  	major = inF.nextInt();MainEllipse.output.printf("%4d  ", major);																		//Writes to in.txt
			   	minor = inF.nextInt();MainEllipse.output.printf("%4d  ", minor);																		//Writes to in.txt
			 	   }
			 
		     MainEllipse.output.close();																												//Closes out.txt																												
	  }
	  /**
	   * Create an Ellipse with dimensions provided by the out.txt.
	   * @Require  major_axis > 0 && minor_axis > 0 || if ( major_axis == minor_axis && major_axis !=0 )|| ( major_axis == minor_axis && major_axis !=1 );
	   * @Ensure  circumference != NaN && area > 0;
	   */  
	  //Imports from a .txt file to fill EllipseArray with previous runtime elements
	  private void historyEllipse () throws IOException {
		  
		    int major = -1;																																//Major variable
		    int minor = -1;																																//Minor variable
		    File fileOut = new File("in.txt");																										    //File out.txt Creation
			  MainEllipse.input = new PrintWriter(new FileWriter(fileOut));																				//Writes to out.txt
			 
			  Scanner inF = new Scanner(new FileReader("out.txt"));																						//Reader for in.txt File
			 	   while(inF.hasNext()){
			    	major = inF.nextInt();MainEllipse.input.printf("%4d  ", major);																		//Writes to out.txt
			    	minor = inF.nextInt();MainEllipse.input.printf("%4d  ", minor);																		//Writes to out.txt
			    	assert major >  0  && minor >  0;																									//Precondition Challenge
				    assert major != 0  && minor != 0;																									//Precondition Challenge
				    this.ellipses.AddEllipse( new Ellipse(major,minor) );
			    	}
			   }
  /**
   * Display top level menu.
   */
	  //Displays user Menu
  private void displayMenu () {
	  out.println("\n\n[OPTIONS]");
	  System.out.println("\nEnter the number denoting the [OPTION] to perform:" +
			    "\n[1]Display major axis"+
			    "\n[2]Display minor axis"+
			    "\n[3]Display area"+
			    "\n[4]Display circumference"+
			    "\n[5]Create new Ellipse"+
			    "\n[6]View History"+ 
			    "\n[7]Save and Exit\n" );
  		}
	
 
  /**
   * Execute user's menu choice.
   */
  //Executes user's choice
  private Choice executeChoice (Choice choice) { 	  
	  	Scanner in = new Scanner(System.in);
	  	int x=0;
	  	x = in.nextInt();																				//Sets UserOption to Enumerated Value
  
  if      (x == 1){ choice = Choice.MAJ_AXS; }	
  else if (x == 2){ choice = Choice.MIN_AXS; } 
  else if (x == 3){	choice = Choice.AREA;	 }
  else if (x == 4){	choice = Choice.CIRCUMF; }
  else if (x == 5){	choice = Choice.NEW;	 }
  else if (x == 6){	choice = Choice.HIST;	 }
  else if (x == 7){ choice = Choice.SAVE;	 }
  return choice;
  }
  
  
  
  
  /**
   * Read an int from system in with the specified prompt.
   */
  //System method to read console keystrokes
  private int readIntWithPrompt (String prompt) {
    out.print(prompt); out.flush();																	//prints console keystroke
    while (!in.hasNextInt()) {	
      in.nextLine();																				//console process user input
      out.print(prompt); out.flush();																//prints user keystroke		
    }
    int input = in.nextInt();																		//int value from user
    in.nextLine();																					
    return input;
  }  
}